package com.service.healthycode.controller;

import com.service.config.annotation.Distinct;
import com.service.config.annotation.Log;
import com.service.config.enums.BusinessType;
import com.service.config.enums.OperatorType;
import com.service.config.utils.*;
import com.service.healthycode.dto.LoginUserDto;
import com.service.healthycode.dto.SmsCode;
import com.service.healthycode.dto.UserDto;
import com.service.healthycode.dto.UserInfoDto;
import com.service.healthycode.entity.UserInfo;
import com.service.healthycode.entity.UserLoginRecords;
import com.service.healthycode.service.UserInfoService;
import com.service.healthycode.service.UserLoginRecordsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;

import static com.service.config.constant.Constant.*;
import static com.service.healthycode.util.TransformationIp.getRealIp;

/**
 * @author: hjl
 * @date: 2022/04/12 15:55
 * @description
 */
@CrossOrigin
@RestController()
@RequestMapping("/userLogin")
@Api(value = "用户 ",tags = "用户接口")
public class UserController {
    @Resource
    private UserInfoService userService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserLoginRecordsService loginService;

    /**
     * 统一登录
     * @param
     * @return
     */
    @RequestMapping(value =  "auth",method = RequestMethod.POST,produces="application/json")
    @ApiOperation(value = "统一登录")
    @ResponseBody
    @Log(isSaveRequestData = true,businessType = BusinessType.QUERY,operatorType = OperatorType.MANAGE)
    public Result loginManage(HttpServletRequest httpServletRequest,
                              @RequestBody LoginUserDto loginUserDto) throws Exception {
        HashMap map;
        if(loginUserDto.getRole().equals(1) && (loginUserDto.getTelephone() == null || "".equals(loginUserDto.getTelephone())
                || "".equals(loginUserDto.getPassword()) || loginUserDto.getPassword() == null)){
            return Result.failure(10003,"用户名或密码为空");
        }else if(loginUserDto.getRole().equals(2) && (loginUserDto.getAccount() == null || "".equals(loginUserDto.getAccount())
                || "".equals(loginUserDto.getPassword()) || loginUserDto.getPassword() == null)){
            return Result.failure(10003,"用户名或密码为空");
        }
        map = userService.getToken(loginUserDto,httpServletRequest);
        if(map == null){
            return Result.failure(USER_NOT_FOUND,"用户名或密码不正确");
        }
        return Result.ok().setData(map);
    }
    /**
     * 用户标准注册
     * @param
     * @return
     */
    @PostMapping(value = "register",produces="application/json")
    @ApiOperation(value = "用户标准注册")
    @ResponseBody
    public Result register(HttpServletRequest httpServletRequest,
                           @RequestBody UserInfoDto userInfoDto) throws Exception {
        if(userInfoDto.getTelephone() == null || "".equals(userInfoDto.getTelephone())
                || "".equals(userInfoDto.getPassword()) || userInfoDto.getPassword() == null){
            return Result.failure(USERNAME_OR_NOTFOUND,"用户名或密码为空,请重新输入");
        }
        String realIp = getRealIp(httpServletRequest);
        HashMap<Object,Object> map = new HashMap<>(16);
        UserInfo register = userService.register(userInfoDto,realIp);
        if (register != null) {
            String token = UserTokenManager.generateToken(register.getId());
            map.put("Token",token);
            UserDto userDto = ModelMapperUtil.strictMap(register, UserDto.class);
            userDto.setIp(realIp); // 来源ip
            userDto.setOnlineTime(new Date()); //登录时间
            redisUtil.setValue(token+register.getId(), JsonXMLUtils.obj2json(userDto)); // 存入缓存
            return Result.ok().setData(map);
        } else {
            return  Result.failure(USERNAME_REPEAT,"用户已存在，请登录");
        }
    }

    /**
     * 点击账号名可查询用户个人信息
     *
     * @param
     * @return
     */
    @RequestMapping(value =  "queryByUser",method = RequestMethod.GET,produces="application/json")
    @ApiOperation(value = "查询用户个人信息")
    @ResponseBody
    @Log(isSaveRequestData = true,businessType = BusinessType.QUERY,operatorType = OperatorType.MANAGE)
    public Result queryOnlineByUser(@RequestHeader(value = "cloud-Auth-Token") String cloudAuthToken) throws Exception {
        if (cloudAuthToken != null && !cloudAuthToken.equals("")) {
            String userId = UserTokenManager.getUserId(cloudAuthToken);
            if (redisUtil.exist(cloudAuthToken + userId)) {
                String value = redisUtil.getValue(cloudAuthToken + userId);
                UserDto userDto = JsonXMLUtils.json2obj(value, UserDto.class);

                UserDto userVo = userService.queryByUserId(userId);
                return Result.ok().setData(userVo);
            } else {
                return Result.failure(10004, "登录信息已失效");
            }
        }
        return Result.failure(USER_NOT_LOGIN, "用户未登录");
    }

    /**
     * 修改个人信息
     * @param
     * @return
     */
    @RequestMapping(value =  "/retrieve",method = RequestMethod.POST,produces="application/json")
    @ApiOperation(value = "修改个人信息")
    @ResponseBody
    @Log(isSaveRequestData = true,businessType = BusinessType.UPDATE,operatorType = OperatorType.MANAGE)
    public Result retrieve(@RequestHeader(value = "cloud-Auth-Token",required = false) String cloudAuthToken,
                           @RequestBody UserInfoDto userInfoDto) throws Exception {
        if (cloudAuthToken != null && !cloudAuthToken.equals("")) {
            String userId = UserTokenManager.getUserId(cloudAuthToken);
            if (redisUtil.exist(cloudAuthToken+userId)) {
                userInfoDto.setId(userId);
                Result result = userService.updateUserInfo(userInfoDto);
                return result;
            }else {
                return Result.failure(10004, "登录信息已失效");
            }
        }
        return Result.ok();
    }

    /**
     * 退出登录
     *
     * @param
     * @return
     */
    @RequestMapping(value =  "logout",method = RequestMethod.GET,produces="application/json")
    @ApiOperation(value = "退出登录")
    @ResponseBody
    @Log(isSaveRequestData = true,businessType = BusinessType.FORCE,operatorType = OperatorType.MANAGE)
    public Result logout(@RequestHeader(value = "cloud-Auth-Token",required = false) String cloudAuthToken,
                         @RequestParam("role") Integer role) throws Exception {
        if (cloudAuthToken != null && !cloudAuthToken.equals("")) {
            String userId = UserTokenManager.getUserId(cloudAuthToken);
            if (redisUtil.exist(cloudAuthToken+userId)) { // 缓存是否存在
                if(role.equals(1)){
                    String value = redisUtil.getValue(cloudAuthToken + userId);
                    UserInfoDto userDto = JsonXMLUtils.json2obj(value, UserInfoDto.class);
                    userDto.setOfflineTime(new Date());
                    userDto.setTime(DateUtil.getDateMin(DateUtil.datetoString(userDto.getOnlineTime()), DateUtil.datetoString(new Date())));
                    userService.updateUserInfo(userDto);
                    redisUtil.leftPush(USER_INFO_HEALTH_CODE,JsonXMLUtils.obj2json(userDto));
                }
                redisUtil.delete(cloudAuthToken+userId);
                return Result.ok();
            }else {
                return Result.failure(10004,"登录信息已失效");
            }
        }else {
            return Result.failure(USER_NOT_LOGIN,"用户未登录");
        }
    }

    /**
     * 清除缓存
     * @param strings
     * @param redisUtil
     */
    public static void clearCache(Set<String> strings, RedisUtil redisUtil) {
        strings.stream().forEach(
                s -> {
                    String value = redisUtil.getValue(s);
                    try {
                        UserDto userDto1 = JsonXMLUtils.json2obj(value, UserDto.class);
                        userDto1.setOfflineTime(new Date());
                        long dateMin = DateUtil.getDateMin(DateUtil.datetoString(userDto1.getOnlineTime()), DateUtil.datetoString(new Date()));
                        userDto1.setTime(dateMin); // 在线时长
                        redisUtil.leftPush(USER_INFO_HEALTH_CODE,JsonXMLUtils.obj2json(userDto1));
                        redisUtil.delete(s);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
        );
    }


}
